package com.hzl.lease.web.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzl.lease.common.constant.RedisConstant;
import com.hzl.lease.common.exception.LeaseException;
import com.hzl.lease.common.result.ResultCodeEnum;
import com.hzl.lease.common.utils.JwtUtil;
import com.hzl.lease.model.entity.SystemUser;
import com.hzl.lease.model.enums.BaseStatus;
import com.hzl.lease.web.admin.mapper.SystemUserMapper;
import com.hzl.lease.web.admin.service.LoginService;
import com.hzl.lease.web.admin.vo.login.CaptchaVo;
import com.hzl.lease.web.admin.vo.login.LoginVo;
import com.wf.captcha.SpecCaptcha;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
//生成图形验证码的方法
    /*验证码需要redis临时保存相关数据，先要在虚拟机开启redis，
    * 同时开启redis服务器已经启动redis客户端，开启指令
    * /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
    */

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SystemUserMapper systemUserMapper;


    @Override
    public CaptchaVo getCaptcha() {
        //图片对象specCaptcha (设置图片的样式)
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);

        //验证码,里面的v值
        String verCode = specCaptcha.text().toLowerCase();
        //redis保存verCode验证码
        String key= RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID();
        redisTemplate.opsForValue().set(key,verCode,RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);


        //把样式的Api描述成图片,和redis保存验证码的key进行封装
        CaptchaVo captchaVo=new CaptchaVo(specCaptcha.toBase64(), key);
        return captchaVo;


    }

    @Override
    public String login(LoginVo loginVo) {
        String captchaCode = loginVo.getCaptchaCode();//get获取验证码

        //①需要先判断传来的验证码是否存在
        if(captchaCode==null){   //表示验证码不存在。直接抛出异常
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND); //验证码不存在
        }

        //如果上述判断验证码传来有数据，则获取redis中的的验证码
        //因为前端传来了loginVo，其中包含信息就有key，所有直接调取方法获取key值
        String redisCode = redisTemplate.opsForValue().get(loginVo.getCaptchaKey());
        //②进行判断key是否存在，因为负载中有到期时间约束，如果验证码过期，key值就为空
        if(redisCode==null){
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);//验证码已过期
        }
        //③再比较传来的验证码的输入是否准确
        if(captchaCode.equals(redisCode)){
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR); //验证码不准确
        }
        /*--只有验证码无误后，再接下来判断传来的用户名和密码是否准确--*/


        //查询传来的账号是否唯一，select（）方法就是查询是否只有一条记录，如果没记录就返回null，有超过一条记录就提示异常
        SystemUser systemUser = systemUserMapper.selectOne(new LambdaQueryWrapper<SystemUser>().eq(SystemUser::getUsername, loginVo.getUsername()));
        if(systemUser == null){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);   //不存在该用户
        }
        //如果有该账户，就要查询此账户是否被禁用
        if(systemUser.getStatus() == BaseStatus.DISABLE){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);  //账号被禁用
        }

        //判断密码是否与数据表中用户的密码一致
        if(systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);  //用户名存在获密码错误
        }

        //全部都比较完后，既输入的登入信息无误，登录成功，再根据你传来的信息，生成token相应给前端
        String token = JwtUtil.createToken(systemUser.getUsername(),systemUser.getId());
        return token;
    }
}
